package com.bestcem.xm.openplatform.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ValidationErrorCodeEnum;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.component.mybatis.base.ResultPage;
import com.bestcem.xm.component.mybatis.service.impl.XmServiceImpl;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.openplatform.entity.OpenplatformExtparam;
import com.bestcem.xm.openplatform.entity.OpenplatformExtparamenummanage;
import com.bestcem.xm.openplatform.grpc.client.DeliverGrpcClient;
import com.bestcem.xm.openplatform.grpc.client.QdesGrpcClient;
import com.bestcem.xm.openplatform.mapper.*;
import com.bestcem.xm.openplatform.mq.dto.OpenplatformExtParamUpdateDto;
import com.bestcem.xm.openplatform.mq.send.biz.OpenplatformMessageSendService;
import com.bestcem.xm.openplatform.service.OpenplatformExtparamenummanageService;
import com.bestcem.xm.openplatform.util.PageUtil;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
@RequiredArgsConstructor
public class OpenplatformExtparamenummanageServiceImpl extends XmServiceImpl<OpenplatformExtparamenummanageMapper, OpenplatformExtparamenummanage> implements OpenplatformExtparamenummanageService {

    private @NonNull OpenplatformExtparamMapper openplatformExtparamMapper;
    private @NonNull OpenplatformEncryptionconfigMapper encryptionconfigMapper;
    private @NonNull OpenplatformSystemmanageMapper systemmanageMapper;
    private @NonNull OpenplatformConditionmanageMapper conditionmanageMapper;
    private @NonNull OpenplatformExtparamenummanageMapper extparamenummanageMapper;
    private @NonNull OpenplatformFunctionoptionMapper functionoptionMapper;

    private @NonNull DeliverGrpcClient deliverGrpcClient;
    private @NonNull QdesGrpcClient qdesGrpcClient;

    private @NonNull OpenplatformMessageSendService openplatformMessageSendService;

    @Override
    public OpenplatformExtparamenummanage getExtParamEnumById(String id) {
        OpenplatformExtparamenummanage obj = baseMapper.selectById(id);
        if (ObjectUtil.isEmpty(obj)) {
            throw new BusinessException("OpenplatformExtparamenummanage[id=" + id + "] not found");
        }
        return obj;
    }

    @Override
    public List<OpenplatformExtparamenummanage> getExtParamEnumList(HttpServletRequest request) {
        String orgId = SecurityContextHolder.getOrgId();
        return baseMapper.selectList(new LambdaQueryWrapper<OpenplatformExtparamenummanage>()
                .eq(OpenplatformExtparamenummanage::getOrgId, orgId)
                .eq(OpenplatformExtparamenummanage::getStatus, 0)
                .eq(StrUtil.isNotBlank(request.getParameter("ext_param_id")), OpenplatformExtparamenummanage::getExtParamId, request.getParameter("ext_param_id")));
    }

    @Override
    public ResultPage<?> getExtParamEnumPage(Page<OpenplatformExtparamenummanage> page, HttpServletRequest request) {
        String orgId = SecurityContextHolder.getOrgId();

        Page<OpenplatformExtparamenummanage> data = baseMapper.selectPage(page,
                new LambdaQueryWrapper<OpenplatformExtparamenummanage>()
                        .eq(OpenplatformExtparamenummanage::getOrgId, orgId)
                        .eq(OpenplatformExtparamenummanage::getStatus, 0)
                        .eq(StrUtil.isNotBlank(request.getParameter("ext_param_id")), OpenplatformExtparamenummanage::getExtParamId, request.getParameter("ext_param_id")));

        List<OpenplatformExtparamenummanage> rows = data.getRecords();
        return PageUtil.getResultPage(data.getCurrent(), data.getTotal(), rows);
    }

    @Override
    public XmResultJson<?> addExtParamEnum(JSONObject params) {
        //判断 ext_param_id
        if (ObjectUtil.isEmpty(params.get("ext_param_id"))) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST.getCode(), "缺少ext_param_id参数");
        }

        //判断 外部参数是否存在
        OpenplatformExtparam extParam = openplatformExtparamMapper.selectById(params.getString("ext_param_id"));
        if (ObjectUtil.isEmpty(extParam)) {
            return XmResultJson.fail(ReqErrorCodeEnum.NOT_FOUND.getCode(), String.format("ext_param[id=%s] not found", params.get("ext_param_id")));
        }
        checkExtCodeAndDesc(params);
        if (!checkExtParamsEnumCodeValid(params, null)) {
            return XmResultJson.fail(ValidationErrorCodeEnum.DATA_DUPLICATE, "编码code重复不可用");
        }
        if (!checkExtParamsEnumDescValid(params, null)) {
            return XmResultJson.fail(ValidationErrorCodeEnum.DATA_DUPLICATE, "业务含义desc重复不可用");
        }

        //发送mq消息
        OpenplatformExtParamUpdateDto dto = new OpenplatformExtParamUpdateDto();
        dto.setExtParamId(params.getString("ext_param_id"));
        dto.setDesc("");
        openplatformMessageSendService.openplatformDeliverSurveyExtVersionUpdateSend(dto);

        OpenplatformExtparamenummanage javaObject = params.toJavaObject(OpenplatformExtparamenummanage.class);
        javaObject.setOrgId(SecurityContextHolder.getOrgId());
        javaObject.setStatus(0);
        baseMapper.insert(javaObject);
        Map<String, Object> ret = new HashMap<>();
        ret.put("id", javaObject.getId());
        return XmResultJson.success(ret);
    }

    private boolean checkExtParamsEnumDescValid(JSONObject params, String id) {
        //检查同一租户、同一外部参数下，枚举名称唯一
        List<OpenplatformExtparamenummanage> ext_params_enum_list = baseMapper.selectList(
                new LambdaQueryWrapper<OpenplatformExtparamenummanage>()
                        .eq(OpenplatformExtparamenummanage::getOrgId, SecurityContextHolder.getOrgId())
                        .eq(OpenplatformExtparamenummanage::getExtParamId, params.getString("ext_param_id"))
                        .eq(OpenplatformExtparamenummanage::getDescription, params.getString("desc"))
                        .eq(OpenplatformExtparamenummanage::getStatus, 0)
        );
        if (ObjectUtil.isEmpty(ext_params_enum_list)) {
            return true;
        }
        //如果是put请求
        return StrUtil.isNotBlank(id) && id.equals(ext_params_enum_list.get(0).getId());
    }

    private boolean checkExtParamsEnumCodeValid(JSONObject params, String id) {
        //检查同一租户、同一外部参数下，枚举名称唯一
        List<OpenplatformExtparamenummanage> ext_params_enum_list = baseMapper.selectList(
                new LambdaQueryWrapper<OpenplatformExtparamenummanage>()
                        .eq(OpenplatformExtparamenummanage::getOrgId, SecurityContextHolder.getOrgId())
                        .eq(OpenplatformExtparamenummanage::getExtParamId, params.getString("ext_param_id"))
                        .eq(OpenplatformExtparamenummanage::getCode, params.getString("code"))
                        .eq(OpenplatformExtparamenummanage::getStatus, 0)
        );
        if (ObjectUtil.isEmpty(ext_params_enum_list)) {
            return true;
        }
        //如果是put请求
        return StrUtil.isNotBlank(id) && id.equals(ext_params_enum_list.get(0).getId());
    }

    private void checkExtCodeAndDesc(JSONObject params) {
        if (ObjectUtil.isEmpty(params.get("code"))) {
            throw new BusinessException(String.valueOf(ReqErrorCodeEnum.PARAM_LOST.getCode()), "缺少code参数");
        }
        if (!checkCodeFormat(params.getString("code"))) {
            throw new BusinessException("编码code只能输入数字字母下划线，最多10个字符");
        }
        if (ObjectUtil.isEmpty(params.get("desc"))) {
            throw new BusinessException(String.valueOf(ReqErrorCodeEnum.PARAM_LOST.getCode()), "缺少desc参数");
        }
        if (params.getString("desc").length() > 50) {
            throw new BusinessException("描述desc最多50个字符");
        }
    }

    private boolean checkCodeFormat(String code) {
        return code.length() <= 10 && code.matches("^[a-zA-Z0-9_]+$");
    }

    @Override
    public XmResultJson<?> updateExtParamEnum(String id, JSONObject param) {
        OpenplatformExtparamenummanage obj = baseMapper.selectById(id);
        if (ObjectUtil.isEmpty(obj)) {
            throw new BusinessException("OpenplatformExtparamenummanage[id=" + id + "] not found");
        }

        if (!Objects.equals(obj.getCode(), param.getString("code"))) {
            throw new BusinessException("编码code不允许被修改");
        }

        checkExtCodeAndDesc(param);
        if (!checkExtParamsEnumCodeValid(param, id)) {
            return XmResultJson.fail(ValidationErrorCodeEnum.DATA_DUPLICATE, "编码code重复不可用");
        }
        if (!checkExtParamsEnumDescValid(param, id)) {
            return XmResultJson.fail(ValidationErrorCodeEnum.DATA_DUPLICATE, "业务含义desc重复不可用");
        }

        OpenplatformExtparamenummanage javaObject = param.toJavaObject(OpenplatformExtparamenummanage.class);
        javaObject.setId(id);
        baseMapper.updateById(javaObject);
        Map<String, Object> ret = new HashMap<>();
        ret.put("id", id);
        return XmResultJson.success(ret);
    }

    @Override
    public XmResultJson<?> deleteExtParamEnum(String id) {
        OpenplatformExtparamenummanage obj = baseMapper.selectById(id);
        if (ObjectUtil.isEmpty(obj)) {
            throw new BusinessException("OpenplatformExtparamenummanage[id=" + id + "] not found");
        }
        obj.setStatus(1);
        baseMapper.updateById(obj);
        Map<String, Object> ret = new HashMap<>();
        ret.put("deletedCount", 1);
        return XmResultJson.success(ret);
    }

}
